package com.sixbro.resource.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;

import static org.springframework.http.HttpMethod.GET;

/**
 * <p>
 *
 * </p>
 *
 * @author: Mr.Lu
 * @since: 2021/11/2 16:45
 */
@Configuration
@EnableWebSecurity
public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure( HttpSecurity http ) throws Exception {
        http
                .csrf( ).disable( )
                .authorizeRequests( authorize -> {
                    authorize
                            // URL匹配filter在PrePost注解之前执行，
                            // 放行包含PrePost注解值为permitAll()的类和方法
                            // to use: @PreAuthorize( "permitAll()" )
//                            .antMatchers( makeRequestMappings( ) ).permitAll( )
//                            .antMatchers( GET, makeGetMappings( ) ).permitAll( )
//                            .antMatchers( POST, makePostMappings( ) ).permitAll( )
//                            .antMatchers( PUT, makePutMappings( ) ).permitAll( )
//                            .antMatchers( DELETE, makeDeleteMappings( ) ).permitAll( )
//                            .antMatchers( PATCH, makePatchMappings( ) ).permitAll( )
                            .antMatchers(GET).permitAll()
                            // 其它的都需认证后才能访问
                            .anyRequest( ).authenticated( );
                })
//                .authorizeRequests(expressionInterceptUrlRegistry -> expressionInterceptUrlRegistry.expressionHandler(defaultWebSecurityExpressionHandler()))
//                .authorizeRequests().expressionHandler(defaultWebSecurityExpressionHandler())
//                .and()
                .oauth2ResourceServer( oauth2 -> {
                    oauth2.jwt( ).jwtAuthenticationConverter( getJwtAuthenticationConverter( ) );
//                    OAuth2WebResponseExceptionTranslator translator = new OAuth2WebResponseExceptionTranslator( );
//                    oauth2.authenticationEntryPoint( translator.authenticationEntryPoint( ) );
//                    oauth2.accessDeniedHandler( translator.accessDeniedHandler( ) );
                } )
                .sessionManagement( session -> session.sessionCreationPolicy( SessionCreationPolicy.STATELESS ) );
    }

    /**
     * To use:
     * `@PreAuthorize( "hasRole( 'roleCode' )" )`
     * `@PreAuthorize( "hasAuthority( 'ROLE_roleCode' )" )`
     *
     * @return Converter
     */
    private Converter< Jwt, AbstractAuthenticationToken > getJwtAuthenticationConverter( ) {
        JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter( );
        jwtGrantedAuthoritiesConverter.setAuthorityPrefix( "ROLE_" );
        jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName( "roles" );

        JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter( );
        authenticationConverter.setJwtGrantedAuthoritiesConverter( jwtGrantedAuthoritiesConverter );
        return authenticationConverter;
    }

//    /**
//     * To use:
//     * `@PreAuthorize( "hasPermission( #foo, 'read' )" )`
//     * `@PreAuthorize( "hasPermission( 1, 'foo', 'create' )" )`
//     *
//     * @return PermissionEvaluator
//     */
//    @Bean
//    public PermissionEvaluator permissionEvaluator( ) {
//        return new DefaultPermissionEvaluator( );
//    }
//
//    @Bean
//    public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
//        DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
//        defaultWebSecurityExpressionHandler.setPermissionEvaluator(permissionEvaluator());
//        return defaultWebSecurityExpressionHandler;
//    }

}
